//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//********************************************************* 

using System;
using System.Diagnostics;
using System.Xml;

namespace Microsoft.TridentWordAddIn.Common
{
    public class DocumentPicture : ICloneable
    {
        #region Fields

        /// <summary>
        /// variable to hold the key value (guid)
        /// </summary>
        private string key;

        #endregion 

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="DocumentImage"/> class.
        /// </summary>
        public DocumentPicture()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DocumentImage"/> class.
        /// </summary>
        /// <param name="key">The key.</param>
        public DocumentPicture(string key)
        {
            this.ParseAttributes(key);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DocumentImage"/> class.
        /// </summary>
        /// <param name="documentPicture">The document picture.</param>
        protected internal DocumentPicture(DocumentPicture documentPicture)
            : this(documentPicture.Key)
        {
        }

        #endregion 

        #region Public members

        /// <summary>
        /// Gets or sets a value indicating whether [appendix picture].
        /// </summary>
        /// <value><c>true</c> if [appendix picture]; otherwise, <c>false</c>.</value>
        public bool AppendixPicture { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [trident link].
        /// </summary>
        /// <value><c>true</c> if [trident link]; otherwise, <c>false</c>.</value>
        public bool TridentLink { get; set; }

        /// <summary>
        /// Gets the key.
        /// </summary>
        /// <value>The key.</value>
        public string Key
        {
            get
            {
                return this.key;
            }
            set
            {
                this.key = value;
            }
        }

        /// <summary>
        /// Gets a value indicating whether this instance has GUID.
        /// </summary>
        /// <value><c>true</c> if this instance has GUID; otherwise, <c>false</c>.</value>
        public bool HasGuid
        {
            get
            {
                return this.key != null;
            }
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"></see> to compare with the current <see cref="T:System.Object"></see>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>; otherwise, false.
        /// </returns>
        public override bool Equals(object obj)
        {
            DocumentPicture documentPicture = obj as DocumentPicture;
            if (documentPicture == null)
            {
                return false;
            }

            return this.Key == documentPicture.Key;
        }

        /// <summary>
        /// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"></see> is suitable for use in hashing algorithms and data structures like a hash table.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"></see>.
        /// </returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        /// <summary>
        /// Creates a guid so that this alt text is guaranteed to be a unique identifier
        /// </summary>
        public void CreateGuid()
        {
            if (this.key == null)
            {
                this.key = "<Guid>" + Guid.NewGuid().ToString() + "</Guid>";
            }
        }
        
        #region ICloneable Members

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public object Clone()
        {
            return new DocumentPicture(this);
        }

        #endregion

        #endregion                      

        #region Private Members

        /// <summary>
        /// Parses the document image attributes.
        /// </summary>
        /// <param name="alternativeText">The alternative text.</param>
        private void ParseAttributes(string alternativeText)
        {
            if (alternativeText.IsNullOrEmpty())
            {
                return;
            }

            XmlDocument xmlDocument = new XmlDocument();
            string xml = "<items>" + alternativeText + "</items>";
            xmlDocument.LoadXml(xml);
            XmlNode guidNode = xmlDocument.DocumentElement.SelectSingleNode("/items/Guid");
            this.key = guidNode != null ? guidNode.OuterXml : null;
            this.AppendixPicture = xmlDocument.DocumentElement.SelectSingleNode("/items/AppendixObject") != null;
            this.TridentLink = xmlDocument.DocumentElement.SelectSingleNode("/items/TridentLink") != null;
        }

        #endregion 
    }
}
